#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <omp.h>
#include "util.h"

#define NUM_PAL 2190828
#define TAM_PAL 15
#define NUM_TH 4

//Numero de palavras 8763309
//Palavras por thread 21908328

int main(int argc, char **argv){

	double tempo, inicial = omp_get_wtime();
	double tempoPal = 0, tempoPalIni = 0, tempoCrivo = 0, tempoCrivoIni = 0;
	int chamadaPalim = 0, chamadaCrivo = 0; 

	FILE *arq;
	char ***texto;
	int i, j;
	int numPalim = 0, primo = 0;
	int teste[4];

	omp_set_num_threads(NUM_TH);
	/* 
    	Faz alocação necessária de memória, levando em conta os dados colhidos
     	em análise feita pela equipe anteriormente a execução, portanto é
     	importante os #define's NUM_TH, NUM_PAL E TAM_PAL estarem preenchidos
     	corretamente 
  	*/
	texto = (char ***)malloc(NUM_TH*sizeof(char **));
	for(i = 0; i < NUM_TH; i++){
		texto[i] = (char **)malloc(NUM_PAL*sizeof(char *));
		for(j = 0; j < NUM_PAL; j++)
			texto[i][j] = (char *)malloc(TAM_PAL*sizeof(char));
	}

	arq = fopen("wikipedia.txt", "r");

	/*
    	Faz a leitura do arquivo e vai preenchendo a estrutura texto, cada thread,
    	ou seja, cada texto[i] recebe uma string j sequencialmente.
  	*/
	for(i = 0; i < NUM_TH; i++){
		for(j = 0; j < NUM_PAL; j++){
			fscanf(arq,"%s", texto[i][j]);
			if(feof(arq))
				break;
			}
	}

	/* 
     	Caso alguma thread não tenha recebido o número máximo de palavras que
     	ela suporta, a posição posterior a última palavra alocada recebe NULL,
    	isto marca o fim das palavras a serem processadas pela thread.
  	*/
	for(; i < NUM_TH; i++)
		for(; j < NUM_PAL; j++)
			texto[i][j] = NULL;

	fclose(arq);
	#pragma omp parallel private (i) reduction (+: numPalim, primo, tempoPal, tempoPalIni, tempoCrivo, tempoCrivoIni, chamadaPalim, chamadaCrivo)
	{
		
		for(i = 0; i < NUM_PAL; i++)
		{
			/* 
				Verifica se a palavra é um palindromo, se for, verifica se
				a soma dos códigos ASCII dos caracteres é um número primo
			*/
			int id = omp_get_thread_num(); 
			chamadaPalim++;
			tempoPalIni = omp_get_wtime();
			int asc = palim(texto[id][i], strlen(texto[id][i]));
			tempoPal = tempoPal + (omp_get_wtime() - tempoPalIni);

			if(asc != 0){
				//printf("%s\n",texto[id][i]);
				numPalim++;
				chamadaCrivo++;
				tempoCrivoIni = omp_get_wtime();
				if(crivo(asc)) {
					primo++;
				}
				tempoCrivo = tempoCrivo + (omp_get_wtime() - tempoCrivoIni);
			}
		}
		printf("Processo %d - Palindromos: [%d , %.2lf] - Primos: [%d , %.2lf]\n",omp_get_thread_num(),chamadaPalim, tempoPal,chamadaCrivo, tempoCrivo);
	}

	tempo = omp_get_wtime() - inicial;

	printf("\n\nNumero de palindromos: %d\n", numPalim);
	printf("Numero de primos: %d\n", primo);
	printf("Tempo de execução: %.2lf seg\n", tempo);
	

return 0;
}

